<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>贪吃蛇</title>
	<style>
	.map{
		width: 500px;
		height: 500px;
		background-color: #E6E6FA;
		position: relative;
	}
	</style>
</head>
<body>
<!-- 地图 -->
<div class="map"></div>
<!-- 自调用函数-食物 -->
<script>
(function (){
	//储存食物DIV
	var elements = [];
	//食物就是一个对象,有宽,有高,有颜色,有横纵坐标,先定义构造函数,然后创建对象
	function Food(x, y, width, height, color) {
        //横纵坐标
        this.x = x || 0;
        this.y = y || 0;
        //宽和高
        this.width = width || 20;
        this.height = height || 20;
        //背景颜色
        this.color = color || "green";
    }
	//为原型添加初始化的方法(作用：在页面上显示这个食物)
	Food.prototype.init = function (map) {
		//删除食物
		remove();
		//创建DIV放入地图中
		var div = document.createElement("div");
		map.appendChild(div);
		//设置样式
		div.style.width = this.width + "px";
        div.style.height = this.height + "px";
        div.style.backgroundColor = this.color;
		div.style.position = "absolute";
		// 让坐标随机分布
		 this.x = parseInt(Math.random() * (map.offsetWidth / this.width)) * this.width;
        this.y = parseInt(Math.random() * (map.offsetHeight / this.height)) * this.height;
        div.style.left = this.x + "px";
        div.style.top = this.y + "px";
		//将生成的DIV推入空数组
		elements.push(div);
	};
	//把空数组里面的DIV食物删掉
	function remove() {
        //elements数组中有这个食物
        for (var i = 0; i < elements.length; i++) {
            var ele = elements[i];
            //找到这个子元素的父级元素,然后删除这个子元素
            ele.parentNode.removeChild(ele);
            //再次把elements中的这个子元素也要删除
            elements.splice(i, 1);
        }
    }

    //把Food暴露给Window,外部可以使用
    window.Food = Food;
}
());

//自调用函数-蛇
(function(){
	//储存蛇的身体部位
	var elements = [];
	//蛇的构造函数
	function Snake(width, height, direction){
		this.width=width||20;
		this.height=height||20;
		this.direction=direction||"right";
		this.body=[
			{x:3,y:2,color:"black"},
			{x:2,y:2,color:"blue"},
			{x:1,y:2,color:"blue"},
		];

	}
	//为原型添加初始化的方法(作用：在页面上显示这条蛇)
	Snake.prototype.init=function(map){
		remove();
		for(var i=0;i<this.body.length;i++){
			var obj = this.body[i];
			var div= document.createElement("div");
			map.appendChild(div);
			//div样式和坐标
			div.style.position="absolute";
			div.style.width=this.width+"px";
			div.style.height=this.height+"px";
			div.style.left=obj.x*this.width+"px";
			div.style.top=obj.y*this.height+"px";
			div.style.backgroundColor=obj.color;
			elements.push(div);
		}
	}
	//为原型添加方法(作用：让这条蛇“动起来”)
	Snake.prototype.move = function (food, map) {
		//此时i是尾巴
		var i =this.body.length-1;
		//通过倒循环,蛇尾前移，改变蛇身体的坐标
		for(;i>0;i--){
			this.body[i].x=this.body[i-1].x;
			this.body[i].y=this.body[i-1].y;
		}
		//通过指令，判断方向,改变蛇头坐标位置，
		switch(this.direction){
			case "right": this.body[0].x+=1;break;
			case "left": this.body[0].x-=1;break;
			case "top": this.body[0].y-=1;break;
			case "bottom": this.body[0].y+=1;break;
		}
		//通过小蛇的头的坐标和食物的坐标是否一致，来判断有没有吃到食物
		var headX = this.body[0].x*this.width;
		var headY = this.body[0].y*this.height;
		//如果一致，就把最后的蛇尾复制一个,重新的加入到小蛇的body中
		if(headX==food.x&&headY==food.y){
			var last=this.body[this.body.length-1];
			this.body.push({
                x:last.x,
                y:last.y,
                color:last.color
            });
            //把食物删除,重新初始化食物
            food.init(map);
		}
	};

	//自调用函数-删除蛇
	function remove(){
		var i=elements.length-1;
		for(;i>=0;i--){
			var ele=elements[i];
			ele.parentNode.removeChild(ele);
			elements.splice(i,1);
		}
	}
	window.Snake = Snake;
}
());

//自调用函数-游戏逻辑
(function(){
	var that = null;//该变量的目的就是为了保存游戏Game的实例对象
	//游戏的构造函数
	function Game(map){
		this.food=new Food();
		this.snake=new Snake();
		this.map=map;
		that = this;
	}

	Game.prototype.init=function(){
		//初始化游戏
        //食物初始化
        this.food.init(this.map);
        //小蛇初始化
        this.snake.init(this.map);
        //调用自动移动小蛇的方法========================||调用了小蛇自动移动的方法
        this.runSnake(this.food, this.map);
        //调用按键的方法
        this.bindKey();//========================================
	};

	Game.prototype.runSnake = function(food,map){
		//设置定时器让蛇自动移动
		var timeId = setInterval(function(){
			//走一步
			this.snake.move(food,map);
			//初始化---重新画一条小蛇(先删除之前的小蛇,把现在的小蛇显示出来)
			this.snake.init(map);

			var maxX = map.offsetWidth / this.snake.width;
			var maxY = map.offsetHeight / this.snake.height;

			var headX = this.snake.body[0].x;
            var headY = this.snake.body[0].y;
            //进行判断
            if(headX<0||headX>=maxX){
            	clearInterval(timeId);
            	alert("很遗憾，你输了");
            }
            if(headY<0||headY>=maxY){
            	clearInterval(timeId);
            	alert("很遗憾，你输了");
            }
		}.bind(that),250);
	};

	//添加原型方法---设置用户按键,改变小蛇移动的方向
	Game.prototype.bindKey=function(){
		document.addEventListener("keydown",function (e) {
			switch(e.keyCode){
				case 37:this.snake.direction="left";break;
                case 38:this.snake.direction="top";break;
                case 39:this.snake.direction="right";break;
                case 40:this.snake.direction="bottom";break;
			}
		}.bind(that),false);
	};
	window.Game=Game;	
}
());


//函数实例化
// var fd = new Food();
// fd.init(document.querySelector(".map"));

	//初始化游戏对象
  var gm = new Game(document.querySelector(".map"));

  //初始化游戏---开始游戏
  gm.init();

</script>
</body>
</html>